package com.witframework.core.persistence;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * oracle blob 操作辅助类
 * @author wuxinyang
 *
 */
public class OracleBlobHelper {

  public OracleBlobHelper() {

  }

  /**
   * 调用newResultSet 的数据库连接
   * @param tableName 表名
   * @param colName 字段名
   * @param condition 条件
   * @param conn 数据库连接
   * @param file 要保存到数据库的文件
   * @throws FileNotFoundException, IOException, SQLException
   */
  public void put(String tableName, String colName, String condition,
                  File file, Connection conn) throws FileNotFoundException, IOException, SQLException {
    InputStream is = new FileInputStream(file);
    this.put(tableName, colName, condition, is, conn);
  }
  

  /**
   *
   * @param is 要保存到数据库的流
   * @param conn 数据库连接（autoCommit 必须为 false）
   * @param tableName 表名
   * @param colName 字段名
   * @param condition 条件
   * @throws SQLException
   * @throws IOException
   */
  public void put(String tableName, String colName, String condition,
                  InputStream is, Connection conn) throws SQLException, IOException {
    //构造条件
    StringBuffer sql = new StringBuffer();
    sql.append("select ");
    sql.append(colName);
    sql.append(" from ");
    sql.append(tableName);
    sql.append(" where ");
    sql.append(condition);
    sql.append(" for update");
    StringBuffer updatesql = new StringBuffer();
    updatesql.append("update ");
    updatesql.append(tableName);
    updatesql.append(" set ");
    updatesql.append(colName);
    updatesql.append("=empty_blob() ");
    updatesql.append(" where ");
    updatesql.append(condition);
    //取数据
    Statement stmt = conn.createStatement();//ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE
    stmt.executeQuery(updatesql.toString());
    ResultSet res = stmt.executeQuery(sql.toString());
    if (res.next()) {
      Blob blob = res.getBlob(1);
      //写数据
      OutputStream os = null;
      /**
       * TODO 改为 oracle.sql.BLOB.getBinaryOutputStream();
       * os = blob.getBinaryOutputStream();
       * byte[] buffer1 = new byte[102400];
       * int len;
       * while ( (len = is.read(buffer1)) != -1) {
       * os.write(buffer1, 0, len);
       * }
       */      
      os.write(blob.getBytes(1, (int) blob.length()));
      is.close();//关闭文件指针
      os.flush();
      os.close();
    }
  }

  

  /**
   *
   * @param tableName 表名
   * @param colName 列名
   * @param condition 条件
   * @param conn 数据库连接（autoCommit 必须为 false）
   * @return InputStream
   * @throws SQLException
   */
  public InputStream getBLOBInputStream(String tableName, String colName,
                                        String condition,
                                        Connection conn) throws SQLException {
    return new ByteArrayInputStream(
        this.getBLOBbyte(tableName, colName, condition, conn));
  }

  
  /**
   * 返回指定Blob字段的字节数组
   * @param tableName 表名
   * @param colName 列名 　
   * @param condition 条件
   * @param conn 数据库连接
   * @return byte[]
   * @throws SQLException
   */
  public byte[] getBLOBbyte(String tableName, String colName, String condition,
                            Connection conn) throws SQLException {
    //构造条件
    StringBuffer sql = new StringBuffer();
    sql.append("select ");
    sql.append(colName);
    sql.append(" from ");
    sql.append(tableName);
    sql.append(" where ");
    sql.append(condition);
    sql.append(" for update ");
    //取数据
    Statement opst = null;
    opst = conn.createStatement();
    ResultSet ors = opst.executeQuery(sql.toString());
    if (ors.next()) {
      Blob blob = ors.getBlob(1);
      if (blob != null) {
        return blob.getBytes(1, (int) blob.length());
      }
      else {
        return null;
      }
    }
    else {
      return null;
    }
  }  
}

